package mollmapsgenerator;


import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.DocumentSource;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author hanis
 */
public class XMLParser {

    public static final String COLLECTION_MOLL_MAPS = "mollMaps";
    public static final String COLLECTION_OLD_MAPS = "oldMaps";
    public static final String COLLECTION_SCHRAM_PORTRAITS = "schramPortraits";
    public static final String COLLECTION_SCHRAM_VEDUTE = "schramVedute";
    


    public static final String PATH_FILESYSTEM = "/home/hanis/projects/mzk03/";
    public static final String SIGNATURE_MAPPING_PATH = "/home/hanis/NetBeansProjects/BarcodePreselector/web/signatureMapping.xml";

    //public static final String PATH = "http://iris.mzk.cz:8080/moll/";
    public static final String PATH = "/";
    public static final String SIGNATURES_PAGE_PATH =  "mollova-sbirka/";
    public static final String RECORD_PAGE_PATH =  "mzk03/";

    public static final String NON_MOLL_RECORD_PAGE_PATH = "mzk03/";

    public static final String URL_PREFIX = "http://imageserver.mzk.cz/mzk03/";

    public static final String PERNAMENT_LINK_ALEPH = "https://aleph.mzk.cz:443/F?func=direct&local_base=MZK03&format=999&doc_number=";


    public static final String OLD_MAPS_LIST_PATH = "sbirka-starych-map/";

    private int couter = 1;


    public static final String OLD_MAPS_LIST_STYLE_PATH= "oldMapsListStyle.xsl";
    public static final String OLD_MAPS_RECORD_STYLE_PATH= "oldMapsRecordStyle.xsl";

    public static final String MOLL_MAPS_LIST_STYLE_PATH= "mollMapsListStyle.xsl";
    public static final String MOLL_MAPS_RECORD_STYLE_PATH= "mollMapsRecordStyle.xsl";


    public XMLParser() {
        
    }

    public static Document getDocument(String urlString, Map nameSpacesMap) {
        Document document = null;
        try {
            URL url = new URL(urlString);

            DocumentFactory factory = new DocumentFactory();
            SAXReader reader = new SAXReader();

            if(nameSpacesMap != null) {
                factory.setXPathNamespaceURIs(nameSpacesMap);
                reader.setDocumentFactory(factory);
            }


            document = reader.read(url);

        } catch (MalformedURLException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (DocumentException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
        return document;
    }


    public static Document getDocument(File file) {
        Document document = null;
        try {
           // URL url = new URL(urlString);

            DocumentFactory factory = new DocumentFactory();
            SAXReader reader = new SAXReader();


            document = reader.read(file);

        } catch (DocumentException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
        return document;
    }



    public String getAlephPernamentLink(String sysno) {
        return PERNAMENT_LINK_ALEPH + sysno;
    }



    public static void main(String[] args) {
     //   try {
            //Map namespaces = new HashMap();
            //namespaces.put( "marc21", "http://www.loc.gov/MARC21/slim" );
            //String xmlUrl = "http://iris.mzk.cz:8080/OaiMzk/Provider?verb=GetRecord&metadataPrefix=marc21&identifier=oai:aleph.mzk.cz:MZK03-001057967";
            //Document document = getDocument(xmlUrl, namespaces);
            //Node node = document.selectSingleNode("//datafield[@tag='100']").selectSingleNode("subfield[@code='a']");
            //Node node = document.selectSingleNode("/leader");
            //    Element root = document.getRootElement();
            //    System.out.println(document.valueOf("//marc21:datafield[@tag='100']/.[@code='a']"));
            //Node node = document.selectSingleNode("//marc21:datafield[@tag='100']");
            //System.out.println(node.selectSingleNode("marc21:subfield[@code='d']").getText());
            //XMLParser.getAllRecordIDs();
            //System.out.println(node.getText());
            XMLParser parser = new XMLParser();
       


//////////////CREATE LAST LEVEL PAGES DIRECTORY STRUCTURE
//            List<String> list = parser.getAllRecordIDs();
//            for (String sysno : list) {
//                System.out.println(sysno);
//            }
       //     parser.findH();

           // parser.createHTML("000903918");
          
            
              
//            System.out.println("_________________________________________________");
//            for (String sysno : parser.getAllRecordIDs()) {
//                System.out.println(sysno);
//            }
//            System.out.println("_________________________________________________");
         //    parser.createRealation();
          //  parser.generateNonMollRecords(COLLECTION_OLD_MAPS, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, OLD_MAPS_LIST_PATH, "Sbírka starých map", -1 ,-1);
//
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_PORTRAITS, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-portrety/", "Schramovy portréty", -1, -1);
//          //  parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty/", "Schramovy veduty");
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-1/", "Schramovy veduty (1)", 0, 200);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-2/", "Schramovy veduty (2)", 201, 400);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-3/", "Schramovy veduty (3)", 401, 600);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-4/", "Schramovy veduty (4)", 601, 800);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-5/", "Schramovy veduty (5)", 801, 1000);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-6/", "Schramovy veduty (6)", 1001, 1200);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-7/", "Schramovy veduty (7)", 1201, 1400);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-8/", "Schramovy veduty (8)", 1401, 1600);
//           parser.generateNonMollRecords(COLLECTION_SCHRAM_VEDUTE, OLD_MAPS_LIST_STYLE_PATH, OLD_MAPS_RECORD_STYLE_PATH, "schramovy-veduty-9/", "Schramovy veduty (9)", 1601, 1800);
//

           parser.getSignatureSet();



   }



    public List<String> getAllRecordIDs(String collectionName, int from, int to) {
        List<String> idSet = new ArrayList<String>();
        String token = null;
        String xmlUrl = "http://iris.mzk.cz:8080/OaiMzk/Provider?verb=ListIdentifiers&resumptionToken=";


        boolean ready = true;
        int counter = 0;
        while (ready) {
            String url;
            if(token == null) {
                url = "http://iris.mzk.cz:8080/OaiMzk/Provider?verb=ListIdentifiers&metadataPrefix=marc21&set=collection:" + collectionName;
            } else {
                url = xmlUrl + token;
            }
            Document document = getDocument(url, null);
            Element root = document.getRootElement();
            List<Node> list = document.selectNodes("//header");
            Node tokenNode = document.selectSingleNode("//resumptionToken");
            if (list.isEmpty() || tokenNode == null) {
                ready = false;
            } else {
                System.out.println(tokenNode.getText());
                token = tokenNode.getText();
            }
            for (Node node : list) {
                counter++;

                String identifier = node.selectSingleNode("identifier").getText();
                String sysno = identifier.substring(identifier.length() - 9, identifier.length());
                Attribute status = ((Element) node).attribute("status");
                if(status != null && status.getValue().equals("deleted")) {
                    System.out.println("deleted:" + sysno);
                    continue; // RECORD DELETED
                }
                if(counter >= from) {
                    if(sysno.equals("001065189")) {
                        System.out.println("CCCC:" + counter);
                    }
                    if(idSet.contains(sysno)) {
                        System.out.println(sysno + ", " + counter);
                    }
                    idSet.add(sysno);
                }

            }
            
            if(to != -1 && counter > to) {
                break;
            }

        }
        
        return idSet;
    }


    public List<String> getAllRecordIDs(String collectionName) {
        return getAllRecordIDs(collectionName, -1, -1);
    }














    public Document getRecordDocument(String sysno) {
        Map namespaces = new HashMap();
        namespaces.put( "marc21", "http://www.loc.gov/MARC21/slim" );
        String xmlUrl = "http://iris.mzk.cz:8080/OaiMzk/Provider?verb=GetRecord&metadataPrefix=marc21&identifier=oai:aleph.mzk.cz:MZK03-" + sysno;
        Document document = getDocument(xmlUrl, namespaces);
        return document;
    }



    public String getRecordIFrame(String sysno) {
        Document document = getRecordDocument(sysno);
        String author = getItem(document, "100", "a");
        String year = getItem(document, "100", "d");
        String name = getItem(document, "245", "a");
        String url = getItem(document, "856", "u");
        
        StringBuilder html = new StringBuilder();
        html.append("<html><head></head><body>");        
        html.append("<h1>").append(name).append("</h1>");
        html.append("<h2>").append(author).append(" ").append(year).append("</h2>");
        html.append("<center><table  style=\"width: 100%\">");
        html.append("<tr><td>");
        html.append("<OBJECT CLASSID=\"clsid:D27CDB 6E-AE6D-11cf-96B8-444553540000\" CODEBASE=\"http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0\" WIDTH=\"800\" HEIGHT=\"700\" ID=\"theMovie\">");
        html.append("<param name=\"movie\" value=\"zoomifyViewer.swf\">");
        html.append("<PARAM NAME=\"MENU\" VALUE=\"FALSE\">");
        html.append("<PARAM NAME=\"SRC\" VALUE=\"zoomifyViewer.swf\">");
        html.append("<EMBED FlashVars=\"zoomifyImagePath=").append(url).append("&zoomifyNavigatorVisible=false\" SRC=\"http://imageserver.mzk.cz/ZoomifyViewer.swf\" MENU=\"FALSE\" PLUGINSPAGE=\"http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash\" WIDTH=\"800\" HEIGHT=\"700\" NAME=\"theMovie\"></EMBED>");
        html.append("</OBJECT></td></tr></table></center>");
        html.append("</body></html>");
        return html.toString();
    }

//    public void test() {
//        Set<String> first = new HashSet<String>();
//        Set<String> second = new HashSet<String>();
//        for (String sysno : getAllRecordIDs()) {
//            Document document = getRecordDocument(sysno);
//
//            Node node = document.selectSingleNode("//marc21:controlfield[@tag='007']");
//            if(node==null) {
//                System.out.println("-----------&&&&&-------------neobsahuje 007 " + sysno);
//                continue;
//            }
//
//            String aaa = node.getText().substring(0,2);
//
//            first.add(aaa.substring(0, 1));
//            second.add(aaa.substring(1, 2));
//
////            if (aaa.charAt(1) == 'y') {
////                System.out.println(sysno);
////            }
//            String ka = getItem(document, "245", "h");
//            if(ka==null) {
//                System.out.println("----------------------------------neobsahuje 245-h " + sysno);
//                continue;
//            }
//            if(ka.startsWith("[ka")) {
//            //System.out.println(getItem(document, "245", "h") + aaa + sysno);
//                System.out.println(aaa + sysno);
//            }
////            Node tagNode = document.selectSingleNode("//marc21:datafield[@tag='505']");
////            Node fff = document.selectSingleNode("//marc21:datafield[@tag='501']");
////            if (tagNode != null && fff != null) {
////                System.out.println(sysno);
////            }
////        }
//        }
//        System.out.println("----------------------");
//        System.out.println(first);
//                System.out.println("----------------------");
//        System.out.println(second);
//    }
//
//    public void findH() {
//        for (String sysno : getAllRecordIDs()) {
//            Document document = getRecordDocument(sysno);
//
//            if(getItem(document, "245", "p") != null) {
//                System.out.println(sysno);
//            }
//        }
//    }



    public void createRealation() {
        Set<RecordsColection> recordCollectionSet = new HashSet<RecordsColection>();
        Set<Record> recordSet = new HashSet<Record>();
        int i = 1;
        for (String sysno : getAllRecordIDs(COLLECTION_MOLL_MAPS)) {
            Document document = getRecordDocument(sysno);
            Record record = new Record(sysno);
            record.setName(getItem(document, "245", "a"));

            record.setOldSignature(getItem(document, "910", "b"));
            String up = getItem(document, "LKR", "a");
            if (up != null && "UP".equals(up)) {
                String sysnoPointer = getItem(document, "LKR", "b");
                if (sysnoPointer != null) {
                    record.setParentSysno(sysnoPointer);
                }
            } else {
                List<String> linkList = getItemList(document, "856", "u");
                RecordsColection rc = new RecordsColection();
                rc.setSignature(record.getOldSignature());
                rc.setMainRecord(record);
                rc.setUrlList(linkList);


            }
            recordSet.add(record);
            System.out.println(i++ + ".." + record);

        }
        assignChildren(recordCollectionSet, recordSet);
        saveCollections2(removeSingleRecords(recordCollectionSet));
    }


    public void assignChildren(Set<RecordsColection> recordCollectionSet, Set<Record> recordSet) {
        int i = 1;
        for (Record record : recordSet) {
           // System.out.println(i++);
            if(record.hasParent()) {
                RecordsColection parentCollection = findCollection(record.getParentSysno(), recordCollectionSet);
              //  System.out.println("ddd");
                if(parentCollection != null) {
                  //  System.out.println("DD");
                    parentCollection.addSysno(record);
                    System.out.println("assign " + record.getSysno() + " to " + record.getParentSysno() + " .......(" + i++ + "+");
                }
            }
        }
    }


    public Set<RecordsColection> removeSingleRecords(Set<RecordsColection> recordCollectionSet) {
        Set<RecordsColection> newRecordCollectionSet = new HashSet<RecordsColection>();
        for (RecordsColection recordsColection : recordCollectionSet) {

            if(recordsColection.getRecordList().size() > 1 && recordsColection.getUrlList().size() > 1) {
                newRecordCollectionSet.add(recordsColection);
            }
        }
        return newRecordCollectionSet;
    }


    public RecordsColection findCollection(String sysno, Set<RecordsColection> recordCollection) {
        for (RecordsColection collection : recordCollection) {            
            if(collection.getMainRecord().getSysno().equals(sysno)) {
                System.out.println("@@@@");
                return collection;
            }
        }
        return null;
    }


    public String getItem(Document document, String tag, String code) {
            Node tagNode = document.selectSingleNode("//marc21:datafield[@tag='" + tag + "']");
            if (tagNode != null) {
                Node codeNode = tagNode.selectSingleNode("marc21:subfield[@code='" + code + "']");
                if(codeNode != null) {
                return codeNode.getText();
            }
        }
        return null;
    }

    public List<String> getItemList(Document document, String tag, String code) {
        List<String> list = new ArrayList<String>();
        List<Node> tagNodelList = document.selectNodes("//marc21:datafield[@tag='" + tag + "']");
        for (Node node : tagNodelList) {
            Node codeNode = node.selectSingleNode("marc21:subfield[@code='" + code + "']");
            if (codeNode != null) {
                list.add(codeNode.getText());
            }
        }
        return list;
    }



    public boolean isSupplemented(Document document) {
        Node tagLKR = document.selectSingleNode("//marc21:datafield[@tag='LKR']");
        Node tag501 = document.selectSingleNode("//marc21:datafield[@tag='501']");
        return tagLKR != null || tag501 != null;
    }


    private void writeDocument(Document document, String path) throws IOException {
        OutputFormat format = OutputFormat.createPrettyPrint();
        XMLWriter writer = new XMLWriter(new FileWriter(path), format);
        writer.write(document);
        writer.close();
    }



    public void saveCollections(Collection<RecordsColection> recordCollectionSet) {
        try {
            Document document = DocumentHelper.createDocument();
            Element root = document.addElement("collections");
            int collectionCounter = 1;
            int recordCounter = 1;
            for (RecordsColection collection : recordCollectionSet) {
                Element elemCollection = root.addElement("collection");
                elemCollection.addAttribute("signature", collection.getSignature());
                elemCollection.addAttribute("id", String.valueOf(collectionCounter++));
                for (String url : collection.getUrlList()) {
                    elemCollection.addElement("url").addText(url);
                }
                for (Record record : collection.getRecordList()) {
                    Element elemRecord = elemCollection.addElement("sysno").addText(record.getSysno());
                    elemRecord.addAttribute("id", String.valueOf(recordCounter++));
                }


            }
            writeDocument(document, "/home/hanis/output6.xml");
        } catch (IOException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void saveCollections2(Collection<RecordsColection> recordCollectionSet) {
        
        try {
            String path = "/home/hanis/collections/";

            for (RecordsColection collection : recordCollectionSet) {
                Document document = DocumentHelper.createDocument();

                Element elemCollection = document.addElement("collection");
                elemCollection.addAttribute("signature", collection.getSignature());
                for (String url : collection.getUrlList()) {
                    elemCollection.addElement("url").addText(url);
                }
                for (Record record : collection.getRecordList()) {
                    Element elemRecord = elemCollection.addElement("sysno").addText(record.getSysno());
                }

                writeDocument(document, path + collection.getSignature().replace("/", "::") + ".xml");
            }
        } catch (IOException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
        saveCollections3(recordCollectionSet);
    }


    public void saveCollections3(Collection<RecordsColection> recordCollectionSet) {
        try {
            Document document = DocumentHelper.createDocument();
            Element root = document.addElement("collections");
            int collectionCounter = 1;
            for (RecordsColection collection : recordCollectionSet) {
                Element elemCollection = root.addElement("collection");
                elemCollection.addAttribute("signature", collection.getSignature());
                elemCollection.addAttribute("date", String.valueOf(Calendar.getInstance().getTime().getTime()));
                elemCollection.addAttribute("status", String.valueOf("new"));
            }
            writeDocument(document, "/home/hanis/collections/collections.xml");
        } catch (IOException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }






//    public void saveThumbnailRSS(SortedSet<Record> recordSet) throws IOException {
//        Document document = DocumentHelper.createDocument();
//        Element root = document.addElement("rss");
//        Element elemChannel = root.addElement("channel");
//
//        int itemCounter = 1;
//        int recordCounter = 0;
//        for (Record record : recordSet) {
//            recordCounter++;
//            for (String url : record.getUrlList()) {
//                Element elemItem = elemChannel.addElement("item");
//                elemItem.addAttribute("signature", record.getOldSignature());
//                elemItem.addAttribute("id",String.valueOf(itemCounter++));
//                elemItem.addAttribute("id2",String.valueOf(recordCounter));
//
//
//                elemItem.addElement("title").addText(record.getName());
//                elemItem.addElement("link").addText(url);
//                Element elemThumb = elemItem.addElement("thumbnail");
//                elemThumb.addAttribute("url", record.getThumbnail(url));
//                //elemItem.addElement("thumbnail").addText(record.getThumbnail(url));
//            //    elemItem.addElement("content").addText(url);
//                elemItem.addElement("old-sig").addText(record.getNewSignatre());
//                elemItem.addElement("sysno").addText(record.getSysno());
//            }
//        }
//        writeDocument(document, "/home/hanis/output155.xml");
//    }


    public void saveThumbnailRSS(SortedSet<Record> recordSet) throws IOException {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("rss");
        Element elemChannel = root.addElement("channel");

        int itemCounter = 1;
        int recordCounter = 0;
        for (Record record : recordSet) {
            recordCounter++;
            for (String url : record.getUrlList()) {
                Element elemItem = elemChannel.addElement("item");
                elemItem.addAttribute("signature", record.getOldSignature());
                elemItem.addAttribute("id",String.valueOf(itemCounter++));
                elemItem.addAttribute("id2",String.valueOf(recordCounter));


                elemItem.addElement("title").addText(record.getName());
                elemItem.addElement("link").addText(url);
                Element elemThumb = elemItem.addElement("thumbnail");
                elemThumb.addAttribute("url", record.getThumbnail(url));
                //elemItem.addElement("thumbnail").addText(record.getThumbnail(url));
            //    elemItem.addElement("content").addText(url);
                elemItem.addElement("old-sig").addText(record.getNewSignatre());
                elemItem.addElement("sysno").addText(record.getSysno());
            }
        }
        writeDocument(document, "/home/hanis/output155.xml");
    }







//    public void getSignatureSet(String prefix) throws IOException {
//        // SortedSet<ThumbnailRecord> thumbnailSet = new TreeSet<ThumbnailRecord>();
//        //SortedSet<Record> recordSet = new TreeSet<Record>();
//        HashMap<String, TreeSet<Record>> map = new HashMap<String, TreeSet<Record>>();
//
//        int i = 1;
//        for (String sysno : getAllRecordIDs()) {
//            Document document = getRecordDocument(sysno);
//            String signature = getItem(document, "Z30", "9");
//            String signaturePrefix = signature.substring(0, signature.lastIndexOf(","));
//
//
//            System.out.println(i++ + ", " + signature);
//            if(signature!= null && signature.startsWith(prefix)) {
//                System.out.println("match");
//                Record record = new Record(sysno);
//                record.setName(getItem(document, "245", "a"));
//                record.setSupplemented(isSupplemented(document));
//                record.setOldSignature(signature);
//                record.setNewSignatre(getItem(document, "Z30", "3"));
//                record.setUrlList(getItemList(document, "856", "u"));
//                record.setSysno(sysno);
//                recordSet.add(record);
//            }
//        }
//        //saveThumbnailRSS(recordSet);
//    }





    public void getSignatureSet() {
        SignatureMappingHandler signatureMapping = getSignatureMapping();
        Map<String, SortedSet<Record>> map = new HashMap<String, SortedSet<Record>>();
        int i = 1;
        int j = 0;
        for (String sysno : getAllRecordIDs(COLLECTION_MOLL_MAPS)) {
            System.out.println(i++);
            Document document = getRecordDocument(sysno);


            ////////// test for hiden recorde////////////////
            String node = getItem(document, "MZK", "s");
            if(node != null) {
                System.out.println("---------------hiddne: " + sysno);
                continue;
            }
            /////////////////////////////


            String signature = getItem(document, "Z30", "9");
            if(signature == null) {
                j++;
                continue;
            }

            if(!signature.startsWith("Moll-0090.900,AA.T.") && !signature.startsWith("Moll-0090.900,AG.T.")) {
                System.out.println("---------------doesnt start with Moll-0090.900,AA.T[G]. : -"+ signature+"- " + sysno);
                continue;
            }


            if(signature.startsWith("Moll-0090.900,AA.T.XXII,")) {
                System.out.println("::::::::::::::::::::::starts with Moll-0090.900,AA.T.XXII,: " + sysno);
            }


            String signaturePrefix = signature.substring(0, signature.indexOf(",", 15));
            SortedSet<Record> recordSet = map.get(signaturePrefix);
            if (recordSet == null) {
                recordSet = new TreeSet<Record>();
                if(signaturePrefix.length() < 20) {
                    System.out.println("//////////////////////////////////////////////////less than 20" + sysno);
                }
                map.put(signaturePrefix, recordSet);
                System.out.println(signaturePrefix);
            }




            if("Moll-0090.900,AA.T-XXIII".equals(signaturePrefix)) {
                System.out.println("@@@@@@@@@@Moll-0090.900,AA.T-XXIII: " + sysno);

            }
            if("Moll-0090.900,AA.T.XXIII".equals(signaturePrefix)) {
                System.out.println("@@@@@@@@@@Moll-0090.900,AA.T.XXIII: " + sysno);

            }


            Record record = new Record(sysno);

            String path = generateCollectionPath(signaturePrefix, false);
            if(path == null) {
                System.out.println("----------------null path::" + sysno);
                continue;
            }
            record.setColectionURL(PATH + SIGNATURES_PAGE_PATH + path);
            record.setCollectionSignature(signaturePrefix);
            

            record.setName(getItem(document, "245", "a"));
            record.setNameOfPart(getItem(document, "245", "p"));
            record.setNumberOfPart(getItem(document, "245", "n"));

            record.setAuthorName(getItem(document, "100", "a"));
            record.setAuthorDate(getItem(document, "100", "d"));

            record.setPublicationPlace(getItem(document, "260", "a"));
            record.setPublicationName(getItem(document, "260", "b"));
            record.setPublicationDate(getItem(document, "260", "c"));
            record.setSupplemented(isSupplemented(document));
            record.setOldSignature(signature);
           // record.setNewSignatre(getItem(document, "Z30", "3"));
           record.setNewSignatre(getItem(document, "910", "b"));

            record.setUrlList(getItemList(document, "856", "u"));
            record.setSysno(sysno);
            for (String s : record.getUrlList()) {
                if (!s.contains("imageserver.mzk")) {
                    System.out.println("!@# --" + s + ", " + sysno);
                }
            }

            record.removeNonImageserverLinks();


            if (!record.getUrlList().isEmpty()) {
                recordSet.add(record);  //////////////////////Add to signature set only if contains at least one link to the imageserver
                createHTML(record, signatureMapping);
            } else {
                System.out.println("----------empty url list: " + sysno);
            }
        }

        for (String s : map.keySet()) {
            System.out.println("----------------------" + s + "-------------------------");
            for (Record recored : map.get(s)) {
                System.out.println(recored.getSysno() + " -- " + recored.getOldSignature() + " - " + recored.getNewSignatre());
            }
        }
        System.out.println("bez z30: " + j);
        try {
            saveSignaturePages(map, signatureMapping);
        } catch (IOException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private String generateCollectionPath(String signaturePrefix, boolean index) {
        if (signaturePrefix != null && signaturePrefix.length() > 18) {
            String roman = signaturePrefix.substring(19);
            String atlas = "atlas-austriacus";
            if (signaturePrefix.contains("AG.T")) {
                atlas = "atlas-germanicus";
            }
            String path = atlas + "/" + roman + "/";
            if (index) {
                path = path + "index.html";
            }
            return path;
        }
        return null;
    }

    public void saveSignaturePages(Map<String, SortedSet<Record>> map, SignatureMappingHandler signatureMapping) throws IOException {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = factory.newTransformer(new StreamSource(new File(MOLL_MAPS_LIST_STYLE_PATH)));

            //    signatureMapping.writeAll();
            for (String signaturePrefix : map.keySet()) {
                try {
                    String path = PATH_FILESYSTEM + SIGNATURES_PAGE_PATH + generateCollectionPath(signaturePrefix, true);
                    try {
                        File file = new File(path);
                        file.getParentFile().mkdirs();
                    } catch (NullPointerException ex) {
                        for (Record r : map.get(signaturePrefix)) {
                            System.out.println(":::::" + r.getSysno() + ", " + r.getNewSignatre() + ", " + r.getOldSignature());
                        }
                        System.out.println("------------4--------------: " + signaturePrefix);
                    }
                    Document document = createSignatureDocument(signaturePrefix, map.get(signaturePrefix), signatureMapping);
                    transformer.transform(new DocumentSource(document), new StreamResult(new FileWriter(path)));
                } catch (TransformerException ex) {
                    Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
                } catch (StringIndexOutOfBoundsException ex) {
                    System.out.println(signaturePrefix + " -- ");
                }
            }
        } catch (TransformerConfigurationException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Document createSignatureDocument(String signaturePrefix, SortedSet<Record> recordSet, SignatureMappingHandler signatureMapping) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("collection");

        if (signaturePrefix != null) {
            root.addAttribute("signaturePrefix", signaturePrefix);
            try {
                root.addAttribute("areaName", signatureMapping.getAreaName(signaturePrefix));

                root.addAttribute("landName", signatureMapping.getLand(signaturePrefix).getName());
                root.addAttribute("landPath", signatureMapping.getLand(signaturePrefix).getPath());
            } catch (NullPointerException e) {
                System.out.println("wrong sig - " + signaturePrefix);
            }
        }
        int k = 0;
        int j = 0;
        for (Record record : recordSet) {
            k++;
            Element elemRecord = root.addElement("record");
            elemRecord.addAttribute("signature", record.getOldSignature());
            elemRecord.addAttribute("signature-new", record.getNewSignatre());
            elemRecord.addAttribute("sysno", record.getSysno());
            elemRecord.addAttribute("supplemented", record.isSupplemented() ? "yes" : "no");

            Element elemTitle = elemRecord.addElement("title");

            elemTitle.addElement("name").addText(record.getName());
            if (record.getNameOfPart() != null) {
                elemTitle.addElement("partName").addText(record.getNameOfPart());
            }
            if (record.getNumberOfPart() != null) {
                elemTitle.addElement("partNumber").addText(record.getNumberOfPart());
            }

            if (record.getAuthorName() != null || record.getAuthorDate() != null) {
                Element elemAuthor = elemRecord.addElement("author");
                elemAuthor.addElement("name").addText(record.getAuthorName() == null ? "" : record.getAuthorName());
                elemAuthor.addElement("date").addText(record.getAuthorDate() == null ? "" : record.getAuthorDate());
            }
            if (record.getPublicationPlace() != null || record.getPublicationName() != null || record.getPublicationDate() != null) {
                Element elemPublication = elemRecord.addElement("publication");
                elemPublication.addElement("place").addText(record.getPublicationPlace() == null ? "" : record.getPublicationPlace());
                elemPublication.addElement("name").addText(record.getPublicationName() == null ? "" : record.getPublicationName());
                elemPublication.addElement("date").addText(record.getPublicationDate() == null ? "" : record.getPublicationDate());
            }


            //Element elemThumbnails = elemRecord.addElement("thumbnails");
            for (String url : record.getUrlList()) {
                j++;
                Element elemThumbnail = elemRecord.addElement("thumbnail");
                elemThumbnail.addElement("url").addText(record.getThumbnail(url));
                elemThumbnail.addElement("map").addText(PATH + RECORD_PAGE_PATH + url.substring(URL_PREFIX.length()));
            }

            if(record.getUrlList().size() > 1 && !record.isSupplemented()) {
                System.out.println("++++++++++++++++++++++++++++++" + record.getSysno());
            }
        }
        System.out.println("RECORDS IN COLLECTION: " + k);
        System.out.println("LINKS IN COLLECTION: " + j);
        return document;
    }





    public void createHTML(String sysno, SignatureMappingHandler signatureMapping) throws TransformerException {
        createHTML(new Record(sysno), signatureMapping);
    }



    public void createHTML(Record record, SignatureMappingHandler signatureMapping)  {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = factory.newTransformer(new StreamSource(new File(MOLL_MAPS_RECORD_STYLE_PATH)));


         //   String sysno = "000903918";
            Document doc = getRecordDocument(record.getSysno());
            List<String> list = getItemList(doc, "856", "u");

            for (String link : list) {
                if (link.startsWith(URL_PREFIX)) {
                    String directory = PATH_FILESYSTEM + RECORD_PAGE_PATH + link.substring(URL_PREFIX.length());
                    File file = new File(directory);
                    file.mkdirs();
                    System.out.println("creating directory: " + directory);
                    String signaturePrefix = record.getCollectionSignature();

                    String areaName = "unknown area";
                    String landName = "unknown land";
                    String landPath = "";

                    try {
                        areaName = signatureMapping.getAreaName(signaturePrefix);
                        landName = signatureMapping.getLand(signaturePrefix).getName();
                        landPath = signatureMapping.getLand(signaturePrefix).getPath();
                    } catch (NullPointerException e) {
                       System.out.println("#######wrong sign." + record.getSysno() + " " + signaturePrefix);
                    }

                    transformer.setParameter("area_name", areaName == null ? "" : areaName);
                    transformer.setParameter("land_name", landName == null ? "" : landName);
                    transformer.setParameter("land_path", landPath == null ? "" : landPath);
                    transformer.setParameter("supplement", record.isSupplemented() ? "yes" : "no");
                    transformer.setParameter("map_url", link);
                    transformer.setParameter("aleph_url", getAlephPernamentLink(record.getSysno()));
                    transformer.setParameter("collection_url", record.getColectionURL());
                    transformer.setParameter("collection_signature", record.getCollectionSignature());
                    //System.out.println("-----------------" + record.getCollectionSignature());
                    transformer.transform(new DocumentSource(getRecordDocument(record.getSysno())), new StreamResult(new FileWriter(directory + "/index.html")));
                }
            }


        } catch (TransformerException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            System.out.println("11");
        }
    }









    public void createMODS(String sysno) throws TransformerException {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = factory.newTransformer(new StreamSource(new File("marctomods.xsl")));


         //   String sysno = "000903918";
            Document doc = getRecordDocument(sysno);
                    transformer.transform(new DocumentSource(getRecordDocument(sysno)), new StreamResult(new FileWriter("output55551.xml")));


        } catch (IOException ex) {
            System.out.println("11");
        } catch (TransformerConfigurationException ex) {
            System.out.println("22");
        }

    }


    public SignatureMappingHandler getSignatureMapping() {
        SignatureMappingHandler signatureMapping = new SignatureMappingHandler();

        Document document = getDocument(new File(SIGNATURE_MAPPING_PATH));
        
        List<Node> mapList = document.selectNodes("//map");
        for (Node node : mapList) {
            String signature = node.selectSingleNode("signature").getText();
            String area = node.selectSingleNode("area").getText();
            signatureMapping.addArea(signature, area);
        }
        
        
        List<Node> landList = document.selectNodes("//land");
        for (Node node : landList) {
            Land land = new Land();
            String name = node.selectSingleNode("name").getText();
            land.setName(name);
            String path = node.selectSingleNode("url").getText();
            land.setPath(path);
            Node signaturesNode = node.selectSingleNode("signatures");
            List<Node> signatureList = signaturesNode.selectNodes("signature");
            for (Node signatureNode : signatureList) {
                String signature = signatureNode.getText();
                land.addSignature(signature);
            }                        
            signatureMapping.addLand(land);
        }

        return signatureMapping;
    }








    public void createNonMollHTML(Record record, String stylePath, String collectionName)  {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = factory.newTransformer(new StreamSource(new File(stylePath)));

            for (String link : record.getUrlList()) {
                    String directory = PATH_FILESYSTEM + NON_MOLL_RECORD_PAGE_PATH + link.substring(URL_PREFIX.length());
                    File file = new File(directory);
                    if(file.exists()) {
                        System.out.println("file exist!!! " + link + ", " + record.getSysno());
                    }
                    file.mkdirs();
                    System.out.println("counter: " + couter++);
                    transformer.setParameter("supplement", record.isSupplemented() ? "yes" : "no");
                    transformer.setParameter("map_url", link);
                    transformer.setParameter("aleph_url", getAlephPernamentLink(record.getSysno()));
                    transformer.setParameter("collection_url", record.getColectionURL());
                    transformer.setParameter("collection_name", collectionName);
                    transformer.transform(new DocumentSource(getRecordDocument(record.getSysno())), new StreamResult(new FileWriter(directory + "/index.html")));
            }


        } catch (TransformerException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            System.out.println("11");
        }
    }







    public void generateNonMollRecords(String collection, String styleListPath, String styleRecordPath, String pagePath, String collectionName, int from, int to) {
        SortedSet<Record> recordSet = new TreeSet<Record>();
        int i = 1;
        int k = 1;
        int j = 0;
        for (String sysno : getAllRecordIDs(collection,from, to)) {
            Document document = getRecordDocument(sysno);


            ////////// test for hiden recorde////////////////
            String node = getItem(document, "MZK", "s");
            if(node != null) {
           //     System.out.println("---------------hiddne: " + sysno);
                continue;
            }
            /////////////////////////////


            String signature = getItem(document, "910", "b");
            if(signature == null) {
                j++;
                continue;
            }

            

            Record record = new Record(sysno);
            record.setColectionURL(PATH + pagePath);

            record.setName(getItem(document, "245", "a"));
            record.setNameOfPart(getItem(document, "245", "p"));
            record.setNumberOfPart(getItem(document, "245", "n"));

            record.setAuthorName(getItem(document, "100", "a"));
            record.setAuthorDate(getItem(document, "100", "d"));

            record.setPublicationPlace(getItem(document, "260", "a"));
            record.setPublicationName(getItem(document, "260", "b"));
            record.setPublicationDate(getItem(document, "260", "c"));
            record.setSupplemented(isSupplemented(document));
            record.setOldSignature(signature);
            record.setNewSignatre(getItem(document, "910", "b"));

            record.setUrlList(getItemList(document, "856", "u"));
            record.setSysno(sysno);
            for (String s : record.getUrlList()) {
                if(!s.contains("imageserver.mzk")) {
                    System.out.println("link points out of imageserver --" + s + ", " + sysno);
                    k++;
                } else {
                   i++;
                }
            }

            record.removeNonImageserverLinks();


            if(!record.getUrlList().isEmpty()) {
//                if(recordSet.contains(record)) {
//                    System.out.println("record set already contains record: " + record.getSysno());
//                }
                recordSet.add(record);
                createNonMollHTML(record, styleRecordPath, collectionName);
            } else {
   //             System.out.println("----------empty url list: " + sysno);
            }
        }
        int h = 0;
        for (Record record : recordSet) {
            h+= record.getUrlList().size();
        }

        System.out.println("collection recordSet links: " + h);
        System.out.println("Collection recorsSet size: " + recordSet.size());
        saveNoMollListPage(recordSet, styleListPath, pagePath, collectionName);
        System.out.println("celkem: " + i + ", jinam: " + k);
        System.out.println("bez 910 b: " + j);

    }





    public void saveNoMollListPage(SortedSet<Record> recordSet, String stylePath, String pagePath, String collectionName) {
        try {
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer;
            transformer = factory.newTransformer(new StreamSource(new File(stylePath)));
            String path = PATH_FILESYSTEM + pagePath + "index.html";
            File file = new File(path);
            file.getParentFile().mkdirs();
            Document document = createSignatureDocument(null, recordSet, null);
            transformer.setParameter("collection_name", collectionName);
            transformer.transform(new DocumentSource(document), new StreamResult(new FileWriter(path)));
        } catch (IOException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        } catch (TransformerException ex) {
            Logger.getLogger(XMLParser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }







}
